﻿using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;

// NOTE: Not the most efficient way to ask for shaders, as it uses Dictionary<name, shader> to store them at the moment - need to work on that.
//       Perhaps array with Enums? considering that shaders will not be unloaded from memory, so there is no need for array flexibility

namespace xEngine.Rendering.Effects
{
    public class PostProcessing
    {
        #region Singleton

        private static PostProcessing inst = new PostProcessing();
        private PostProcessing()
        {
            _initialized = false;
        }

        #endregion

        #region Member Variables

        private SpriteBatch _spriteBatch;
        private RenderTarget2D _tempRT;
        private bool _initialized;

        private PPGaussianBlur _gaussianBlur;
        private PPSplitViewHorizontal _splitViewHorizontal;

        #endregion

        #region Functions

        private static bool Ready()
        {
            bool ready = true;

            if (inst._spriteBatch == null)
            {
                try
                {
                    inst._spriteBatch = new SpriteBatch(RenderManager.Device);
                }
                catch (Exception e)
                {
                    Debugging.LogWriter.WriteLine = "Error initializing PostProcessor -> SpriteBatch. " + e.Message;
                    ready = false;
                }
            }

            if (inst._tempRT == null)
            {
                try
                {
                    inst._tempRT = new RenderTarget2D(RenderManager.Device,
                                                      RenderManager.Device.PresentationParameters.BackBufferWidth,
                                                      RenderManager.Device.PresentationParameters.BackBufferHeight,
                                                      false,
                                                      SurfaceFormat.Color,
                                                      DepthFormat.Depth24Stencil8,
                                                      0,
                                                      RenderTargetUsage.DiscardContents);
                }
                catch (Exception e)
                {
                    Debugging.LogWriter.WriteLine = "Error initializing PostProcessor -> TempRenderTarget. " + e.Message;
                    ready = false;
                }
            }

            if (!inst._initialized)
            {
                try
                {
                    InitPP();
                    inst._initialized = true;
                }
                catch (Exception e)
                {
                    Debugging.LogWriter.WriteLine = "Error initializing PostProcessor -> PostProcessors. " + e.Message;
                    ready = false;
                }
            }
            return ready;
        }
        private static void InitPP()
        {
            inst._gaussianBlur = new PPGaussianBlur(inst._spriteBatch, inst._tempRT);
            inst._splitViewHorizontal = new PPSplitViewHorizontal(inst._spriteBatch);
        }

        public static void GaussianBlur(RenderTarget2D input, RenderTarget2D output, bool useFullScreen)
        {
            if (!Ready())
                return;

            inst._gaussianBlur.GaussianBlur(input, output, useFullScreen);
        }
        public static void SplitViewHorizontal(RenderTarget2D input, RenderTarget2D output, int amount)
        {
            if (!Ready())
                return;

            inst._splitViewHorizontal.SplitViewHorizontal(input, output, amount);
        }

        #endregion
    }
}
